import router from './router'
import store from './store'
import { Message } from 'element-ui'
import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css' // progress bar style
import { getToken } from '@/utils/auth' // getToken from cookie

// NProgress Configuration
NProgress.configure({
  showSpinner: false
})

// permission judge function
function hasPermission(roles, permissionRoles) {
  // admin permission passed directly
  if (roles.indexOf('admin') >= 0) return true
  if (!permissionRoles) return true
  return roles.some(role => permissionRoles.indexOf(role) >= 0)
}

// no redirect whitelist
const whiteList = ['/login', '/auth-redirect']

router.beforeEach((to, from, next) => {
  NProgress.start()
  // 如果已经有登录凭证
  if (getToken()) {
    // 如果访问的是登录路由则直接跳转到首页
    if (to.path === '/login') {
      next({ path: '/' })
      NProgress.done()
    }
    // 如果是其他页面的路由
    else {
      // 检查是否拉取用户角色权限
      // 如果没有拉取
      if (store.getters.roles.length === 0) {
        // 则重新拉取用户权限
        store.dispatch('GetUserInfo').then(res => {
          // const roles = res.data.authorities
          const roles = []
          // 根据 roles 权限生成可访问的路由表
          store.dispatch('GenerateRoutes', { roles }).then(() => {
            // 动态添加可访问路由
            router.addRoutes(store.getters.addRouters)
            next({ ...to, replace: true })
          }).catch(err => {
            store.dispatch('FedLogout').then(() => {
              Message.error(err || '验证失败，请重新登录！')
              next({ path: '/' })
            })
          })
        })
      }
      // 如果有角色权限
      else {
        // 判断是否有符合权限的路由
        if (hasPermission(store.getters.roles, to.meta.roles)) {
          next()
        } else {
          next({ path: '/401', replace: true, query: { noGoBack: true }})
        }
      }
    }
  }
  // 如果没有登录Token
  else {
    // 检查白名单
    if (whiteList.indexOf(to.path) !== -1) {
      // 在白名单里的直接进入
      next()
    }
    // 否则重定向到登录页
    else {
      next(`/login?redirect=${to.path}`)
      NProgress.done()
    }
  }
})

router.afterEach((to, from) => {
  NProgress.done()
})
